package com.witmore.neutron.ai.web.apiv2.nls;

import com.alibaba.nls.client.AccessToken;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class NlsTokenCache {


    private final ConcurrentHashMap<String, TokenInfo> tokenCache = new ConcurrentHashMap<>();

    @Autowired
    private NlsTokenClient nlsTokenClient;

    /**
     * 获取token的方法，首先从缓存中查找
     */
    public String getToken() {
        TokenInfo tokenInfo = tokenCache.get("token");
        // 如果token存在且有效
        if (!isTokenExpired()) {
            log.info("Token from cache: {}", tokenInfo.getToken());
            return tokenInfo.getToken();
        }
        return refreshToken();
    }

    /**
     * 刷新token
     */
    public String refreshToken() {
        removeToken();
        TokenInfo tokenInfo;
        AccessToken newToken;
        try {
            newToken = nlsTokenClient.getAccessToken();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        tokenInfo = new TokenInfo(newToken.getToken(), newToken.getExpireTime());
        tokenCache.put("token", tokenInfo);
        return newToken.getToken();
    }

    /**
     * 删除token缓存信息
     */
    private void removeToken() {
        tokenCache.remove("token");
    }

    /**
     * 检查 Token 是否过期
     */
    private boolean isTokenExpired() {
        if (CollectionUtils.isEmpty(tokenCache)) {
            return true;
        }
        TokenInfo tokenInfo = tokenCache.get("token");
        return tokenInfo == null || tokenInfo.getToken() == null
                || tokenInfo.isExpired();
    }

    /**
     * Token信息类，包含token和过期时间
     */
    @Data
    static class TokenInfo {
        private String token;
        private long expiryTime;

        public TokenInfo(String token, long expiryTime) {
            this.token = token;
            this.expiryTime = expiryTime;
        }

        public boolean isExpired() {
            return System.currentTimeMillis() > expiryTime;
        }
    }
}
